<template>
  <div class="image-compressor">
    <el-card class="tool-card">
      <template #header>
        <div class="card-header">
          <h3>图片压缩工具</h3>
          <el-tag v-if="hasPro" type="warning" size="small">PRO</el-tag>
        </div>
      </template>
      
      <div class="tool-description">
        <p>压缩图片文件大小，同时尽可能保持图片质量。支持JPG、PNG和WebP格式。</p>
      </div>
      
      <!-- 权限提示 -->
      <div class="pro-features" v-if="!isPro">
        <el-alert
          title="免费版功能限制"
          type="info"
          :closable="false"
          show-icon
        >
          <template #default>
            <div class="limit-info">
              <p>· 单文件 ≤ 5MB，每天最多10次</p>
              <p>· 仅支持JPG/PNG格式</p>
              <p>· 输出图片添加水印</p>
              <p>· 仅支持有损压缩模式</p>
            </div>
            <el-button type="warning" size="small" @click="handleUpgrade">
              升级Pro版解锁高级功能
            </el-button>
          </template>
        </el-alert>
      </div>
      
      <!-- 上传区域 -->
      <div class="upload-area">
        <div class="upload-card">
          <h4>图片上传</h4>
          <el-upload
            ref="uploadRef"
            class="image-uploader"
            :action="uploadAction"
            :multiple="isPro"
            :limit="isPro ? 20 : 1"
            :on-exceed="handleExceed"
            :before-upload="beforeUpload"
            :on-success="handleSuccess"
            :on-error="handleError"
            :on-change="handleChange"
            :auto-upload="false"
            :show-file-list="true"
            drag
          >
            <el-icon class="upload-icon"><Upload /></el-icon>
            <div class="upload-text">拖拽图片到此处或<em>点击上传</em></div>
            <div class="upload-tip">
              {{ isPro ? '支持JPG、PNG、WebP格式，最大50MB' : '支持JPG、PNG格式，最大5MB' }}
            </div>
          </el-upload>

          <!-- 添加图片预览区域 -->
          <div class="upload-preview" v-if="previewImageUrl">
            <div class="preview-header">
              <h5>图片预览</h5>
              <el-button 
                type="danger" 
                size="small" 
                icon="Delete" 
                circle 
                @click="removeUploadedImage"
                title="移除图片"
              ></el-button>
            </div>
            <div class="preview-image-container">
              <img :src="previewImageUrl" alt="预览图" class="preview-image" />
              <div class="preview-info">
                <span>{{ previewImageName }}</span>
                <span>{{ previewImageSize }}</span>
              </div>
            </div>
          </div>
        </div>

        <!-- 压缩设置 -->
        <div class="settings-card">
          <h4>压缩设置</h4>
          
          <el-form label-position="top" :model="settings" class="settings-form">
            <el-form-item label="质量调节">
              <el-slider 
                v-model="settings.quality" 
                :min="10" 
                :max="100" 
                :step="1"
                :marks="{
                  10: '10%',
                  25: '25%',
                  50: '50%',
                  75: '75%',
                  100: '100%'
                }"
                show-input
              />
            </el-form-item>
            
            <el-form-item label="分辨率调整">
              <el-checkbox v-model="settings.resize">等比缩放图片</el-checkbox>
              <el-input-number 
                v-if="settings.resize"
                v-model="settings.maxSize" 
                :min="100" 
                :max="isPro ? 4000 : 2000" 
                :step="100"
                :disabled="!settings.resize"
              >
                <template #suffix>px (最长边)</template>
              </el-input-number>
            </el-form-item>
            
            <el-form-item label="压缩模式">
              <el-radio-group v-model="settings.mode">
                <el-radio label="lossy" :disabled="!isPro">有损压缩</el-radio>
                <el-tooltip content="需要Pro版" placement="top" :disabled="isPro">
                  <el-radio label="lossless" :disabled="!isPro">无损压缩</el-radio>
                </el-tooltip>
              </el-radio-group>
            </el-form-item>
            
            <el-form-item label="输出格式" v-if="isPro">
              <el-radio-group v-model="settings.outputFormat">
                <el-radio label="same">保持原格式</el-radio>
                <el-radio label="webp">转换为WebP</el-radio>
              </el-radio-group>
            </el-form-item>
            
            <el-form-item label="水印设置" v-if="isPro">
              <el-checkbox v-model="settings.addWatermark">添加自定义水印</el-checkbox>
              <div v-if="settings.addWatermark" class="watermark-settings">
                <el-tabs v-model="settings.watermarkType">
                  <el-tab-pane label="文字水印" name="text">
                    <el-input v-model="settings.watermarkText" placeholder="请输入水印文字"></el-input>
                  </el-tab-pane>
                  <el-tab-pane label="图片水印" name="image">
                    <el-upload
                      class="watermark-uploader"
                      action="#"
                      :auto-upload="false"
                      :show-file-list="false"
                    >
                      <img v-if="watermarkImageUrl" :src="watermarkImageUrl" class="watermark-image" />
                      <el-icon v-else class="watermark-uploader-icon"><Plus /></el-icon>
                    </el-upload>
                  </el-tab-pane>
                </el-tabs>
              </div>
            </el-form-item>
          </el-form>
          
          <div class="compression-actions">
            <el-button type="primary" @click="startCompression" :loading="isCompressing">
              开始压缩
            </el-button>
            <el-button @click="resetForm">重置</el-button>
          </div>
        </div>
      </div>
      
      <!-- 压缩进度 -->
      <div class="compression-progress" v-if="isCompressing">
        <el-progress 
          :percentage="compressionProgress" 
          :format="progressFormat"
          :stroke-width="18"
          status="success"
        ></el-progress>
        <div class="progress-info">
          <p>预计剩余时间: {{ remainingTime }}</p>
        </div>
      </div>
      
      <!-- 结果预览 -->
      <div class="results-area">
        <h4>压缩结果</h4>
        
        <el-table :data="compressionResults" style="width: 100%">
          <el-table-column prop="fileName" label="文件名" width="180"></el-table-column>
          <el-table-column label="大小变化">
            <template #default="scope">
              <div class="size-change">
                <span>{{ formatFileSize(scope.row.originalSize) }}</span>
                <el-icon><ArrowRight /></el-icon>
                <span>{{ formatFileSize(scope.row.compressedSize) }}</span>
              </div>
              <div class="compression-rate">
                <el-progress 
                  :percentage="Math.round((1 - scope.row.compressedSize / scope.row.originalSize) * 100)"
                  :stroke-width="10"
                  :format="val => formatSizeChange(scope.row.originalSize, scope.row.compressedSize)"
                  :color="scope.row.originalSize > scope.row.compressedSize ? '#3498db' : '#e6a23c'"
                ></el-progress>
              </div>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="180">
            <template #default="scope">
              <el-button size="small" @click="previewImage(scope.row)">预览</el-button>
              <el-button size="small" type="primary" @click="downloadImage(scope.row)">下载</el-button>
            </template>
          </el-table-column>
        </el-table>
        
        <div class="batch-actions" v-if="compressionResults.length > 1 && isPro">
          <el-button type="primary" @click="downloadAll">打包下载全部</el-button>
        </div>
      </div>
      
      <!-- 图片预览对话框 -->
      <el-dialog v-model="previewVisible" title="图片对比预览" width="80%" :modal="true" :lock-scroll="true" :close-on-click-modal="true">
        <div class="image-comparison" v-if="currentPreview">
          <div class="comparison-container">
            <div class="comparison-original">
              <h4>原图</h4>
              <div class="image-wrapper">
                <img :src="currentPreview.originalUrl" alt="原图" />
              </div>
              <div class="image-info">
                <p>{{ formatFileSize(currentPreview.originalSize) }}</p>
              </div>
            </div>
            <div class="comparison-compressed">
              <h4>压缩后</h4>
              <div class="image-wrapper">
                <img :src="currentPreview.compressedUrl" alt="压缩后" />
              </div>
              <div class="image-info">
                <p>{{ formatFileSize(currentPreview.compressedSize) }}</p>
                <p>{{ formatSizeChange(currentPreview.originalSize, currentPreview.compressedSize) }}</p>
              </div>
            </div>
          </div>
        </div>
      </el-dialog>
      
      <!-- 使用指南 -->
      <section class="usage-section">
        <div class="usage-wrapper">
          <div class="usage-title-section">
            <el-icon size="28" class="usage-icon"><Guide /></el-icon>
            <h2>快速使用指南</h2>
          </div>
          <div class="usage-content">
            <div class="guide-steps">
              <div class="step-item">
                <div class="step-number">1</div>
                <div class="step-content">
                  <h4>上传图片</h4>
                  <p>将图片拖拽到上传区域或点击上传</p>
                </div>
              </div>
              <div class="step-item">
                <div class="step-number">2</div>
                <div class="step-content">
                  <h4>设置参数</h4>
                  <p>调整压缩质量、分辨率和其他设置</p>
                </div>
              </div>
              <div class="step-item">
                <div class="step-number">3</div>
                <div class="step-content">
                  <h4>开始压缩</h4>
                  <p>点击"开始压缩"按钮处理图片</p>
                </div>
              </div>
              <div class="step-item">
                <div class="step-number">4</div>
                <div class="step-content">
                  <h4>获取结果</h4>
                  <p>压缩完成后预览效果并下载</p>
                </div>
              </div>
            </div>
            <div class="pro-tip" v-if="!isPro">
              <el-icon><Star /></el-icon>
              <span><strong>提示：</strong> 升级到Pro会员可以解锁批量处理、无损压缩、WebP转换和自定义水印等高级功能</span>
            </div>
          </div>
        </div>
      </section>
      
      <!-- 错误提示 -->
      <el-dialog v-model="errorVisible" title="错误" width="30%">
        <div class="error-message">
          <el-alert
            :title="errorMessage"
            type="error"
            :closable="false"
            show-icon
          >
          </el-alert>
        </div>
        <template #footer>
          <span class="dialog-footer">
            <el-button @click="errorVisible = false">关闭</el-button>
            <el-button type="primary" v-if="errorNeedsPro" @click="handleUpgrade">
              升级Pro版
            </el-button>
          </span>
        </template>
      </el-dialog>
    </el-card>
  </div>
</template>

<script setup>
/**
 * 图片压缩组件
 * 支持JPG、PNG、WebP格式的图片压缩功能
 * 
 * @features
 * - 有损/无损压缩（无损仅限Pro用户）
 * - 调节质量和分辨率
 * - 批量处理（仅限Pro用户）
 * - 自定义水印（仅限Pro用户）
 * - 支持WebP输出（仅限Pro用户）
 */
import { ref, computed, watch, reactive, onMounted, onUnmounted } from 'vue';
import { useStore } from 'vuex';
import { ElMessage, ElLoading } from 'element-plus';
import { 
  Upload, Plus, ArrowRight,
  Picture, Download, Setting, Guide, Star, Delete
} from '@element-plus/icons-vue';
import UsageGuide from '../../common/UsageGuide.vue';
import { useRouter } from 'vue-router';

// 存储实例
const store = useStore();
const router = useRouter();

// 会员状态
const isPro = computed(() => store.getters.isPro || false);
const hasPro = computed(() => !!store.getters.isPro);

// 上传引用和配置
const uploadRef = ref(null);
const uploadAction = '#'; // 实际上传将由前端处理，不会发送到服务器

// 当前状态
const isCompressing = ref(false);
const compressionProgress = ref(0);
const remainingTime = ref('计算中...');
const compressionResults = ref([]);
const previewVisible = ref(false);
const currentPreview = ref(null);
const errorVisible = ref(false);
const errorMessage = ref('');
const errorNeedsPro = ref(false);
const watermarkImageUrl = ref('');
const previewImageUrl = ref('');
const previewImageName = ref('');
const previewImageSize = ref('');

// 压缩设置
const settings = reactive({
  quality: 75, // 默认75%的质量
  resize: false,
  maxSize: 2000, // 默认最大2000px
  mode: 'lossy', // 默认有损压缩
  outputFormat: 'same', // 默认保持原格式
  addWatermark: false, // 默认不添加水印
  watermarkType: 'text', // 默认文字水印
  watermarkText: '柯基工具箱' // 默认水印文字
});

// 文件类型限制
const acceptedTypes = computed(() => {
  if (isPro.value) {
    return ['image/jpeg', 'image/png', 'image/webp'];
  }
  return ['image/jpeg', 'image/png'];
});

// 文件大小限制（字节）
const maxFileSize = computed(() => {
  if (isPro.value) {
    return 50 * 1024 * 1024; // 50MB for Pro
  }
  return 5 * 1024 * 1024; // 5MB for free
});

// 格式化文件大小
const formatFileSize = (bytes) => {
  if (bytes === 0) return '0 Bytes';
  const k = 1024;
  const sizes = ['Bytes', 'KB', 'MB', 'GB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
};

// 格式化进度显示
const progressFormat = (percentage) => {
  return `${percentage}% 已完成`;
};

// 检查文件是否符合要求
const beforeUpload = (file) => {
  // 检查文件类型
  if (!acceptedTypes.value.includes(file.type)) {
    showError(`仅支持${isPro.value ? 'JPG/PNG/WebP' : 'JPG/PNG'}格式，请重新上传。`);
    return false;
  }
  
  // 检查文件大小
  if (file.size > maxFileSize.value) {
    showError(`文件超出限制，${isPro.value ? '最大50MB' : '升级Pro版解锁50MB支持！'}`, !isPro.value);
    return false;
  }
  
  // 检查今日次数（仅免费用户）
  if (!isPro.value && checkDailyLimit()) {
    showError('今日免费压缩次数已用完，请明天再试或升级Pro版！', true);
    return false;
  }
  
  return true;
};

// 检查今日使用次数
const checkDailyLimit = () => {
  // 实际应用中应从服务器获取次数
  // 这里模拟本地存储的逻辑
  const today = new Date().toISOString().split('T')[0];
  const usageKey = `img_compress_usage_${today}`;
  
  let usage = localStorage.getItem(usageKey);
  usage = usage ? parseInt(usage) : 0;
  
  return usage >= 10; // 超过10次返回true
};

// 记录使用次数
const recordUsage = () => {
  if (isPro.value) return; // Pro用户不限次数
  
  const today = new Date().toISOString().split('T')[0];
  const usageKey = `img_compress_usage_${today}`;
  
  let usage = localStorage.getItem(usageKey);
  usage = usage ? parseInt(usage) : 0;
  usage += 1;
  
  localStorage.setItem(usageKey, usage.toString());
};

// 处理上传超限
const handleExceed = () => {
  ElMessage.warning(`最多可选择${isPro.value ? '20' : '1'}张图片`);
};

// 文件变化处理
const handleChange = (file, fileList) => {
  // 预览上传的图片
  if (file.raw) {
    const reader = new FileReader();
    reader.onload = (e) => {
      previewImageUrl.value = e.target.result;
      previewImageName.value = file.name;
      previewImageSize.value = formatFileSize(file.size);
    };
    reader.readAsDataURL(file.raw);
  }
};

// 上传成功处理
const handleSuccess = (response, file, fileList) => {
  // 这里不会实际调用，因为我们用的是自定义上传
};

// 上传错误处理
const handleError = (err) => {
  showError('上传失败，请重试');
};

// 显示错误信息
const showError = (message, needsPro = false) => {
  errorMessage.value = message;
  errorNeedsPro.value = needsPro;
  errorVisible.value = true;
};

// 开始压缩
const startCompression = async () => {
  // 检查是否有文件
  if (!previewImageUrl.value) {
    showError('请先选择要压缩的图片');
    return;
  }
  
  // 开始压缩流程
  isCompressing.value = true;
  compressionProgress.value = 0;
  compressionResults.value = [];
  
  try {
    // 获取上传的文件
    const uploadFiles = uploadRef.value?.uploadFiles || [];
    
    // 如果没有文件但有预览图片，说明文件已被处理但uploadFiles为空
    if (uploadFiles.length === 0 && previewImageUrl.value) {
      // 创建一个虚拟文件对象
      const fakeFile = {
        name: previewImageName.value,
        size: parseFileSizeToBytes(previewImageSize.value),
        type: guessFileTypeFromUrl(previewImageUrl.value),
        raw: await urlToFile(previewImageUrl.value, previewImageName.value)
      };
      
      // 更新进度信息
      compressionProgress.value = 5;
      remainingTime.value = '处理中...';
      
      await processImage(fakeFile.raw);
      compressionProgress.value = 100;
      remainingTime.value = '已完成';
    } else {
      // 使用实际的文件列表
      const files = [...uploadFiles];
      const totalFiles = files.length;
      
      for (let i = 0; i < files.length; i++) {
        const file = files[i];
        
        // 更新进度信息
        compressionProgress.value = Math.round(((i) / totalFiles) * 90);
        remainingTime.value = `正在处理第 ${i+1}/${totalFiles} 个文件...`;
        
        await processImage(file.raw);
        
        // 更新真实进度
        compressionProgress.value = Math.round(((i + 1) / totalFiles) * 100);
        remainingTime.value = i === totalFiles - 1 ? '已完成' : `剩余 ${totalFiles - i - 1} 个文件`;
      }
    }
    
    // 记录使用
    recordUsage();
    store.commit('recordFunctionUsage', {
      functionName: '图片压缩工具',
      isPro: isPro.value
    });
    
    // 显示完成消息
    ElMessage.success('压缩完成！');
  } catch (error) {
    console.error('压缩过程出错:', error);
    showError('压缩失败，请重试');
  } finally {
    isCompressing.value = false;
  }
};

// 处理单个图片
const processImage = (file) => {
  return new Promise((resolve) => {
    // 创建文件读取器
    const reader = new FileReader();
    
    reader.onload = (e) => {
      // 原始图片数据
      const originalDataUrl = e.target.result;
      
      // 创建图片元素以获取尺寸
      const img = new Image();
      img.onload = () => {
        // 获取原始尺寸
        let width = img.width;
        let height = img.height;
        const originalSize = file.size;
        
        // 处理分辨率调整
        if (settings.resize) {
          const maxSize = settings.maxSize;
          if (width > height && width > maxSize) {
            height = Math.round((height * maxSize) / width);
            width = maxSize;
          } else if (height > width && height > maxSize) {
            width = Math.round((width * maxSize) / height);
            height = maxSize;
          } else if (width > maxSize && height > maxSize) {
            if (width > height) {
              height = Math.round((height * maxSize) / width);
              width = maxSize;
            } else {
              width = Math.round((width * maxSize) / height);
              height = maxSize;
            }
          }
        }
        
        // 创建Canvas进行压缩
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');
        canvas.width = width;
        canvas.height = height;
        
        // 绘制图片
        ctx.fillStyle = '#FFFFFF'; // 设置白色背景
        ctx.fillRect(0, 0, width, height);
        ctx.drawImage(img, 0, 0, width, height);
        
        // 添加水印（如果需要）
        if (!isPro.value || (isPro.value && settings.addWatermark)) {
          ctx.fillStyle = 'rgba(255, 255, 255, 0.5)';
          ctx.fillRect(width - 150, height - 40, 140, 30);
          
          ctx.font = '14px Arial';
          ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
          ctx.textAlign = 'center';
          ctx.textBaseline = 'middle';
          const watermarkText = isPro.value && settings.addWatermark ? settings.watermarkText : '柯基工具箱';
          ctx.fillText(watermarkText, width - 80, height - 25);
        }
        
        // 确定输出格式和质量
        let outputFormat, quality, compressedDataUrl;
        
        // 智能格式选择：保持原始图片的格式
        if (isPro.value && settings.outputFormat === 'webp') {
          outputFormat = 'image/webp';
        } else {
          // 尽量保持原格式，除非特殊指定
          if (file.type === 'image/png' && settings.mode === 'lossless' && isPro.value) {
            outputFormat = 'image/png';
            quality = 1.0; // PNG无损质量
          } else if (file.type === 'image/webp') {
            outputFormat = 'image/webp';
          } else {
            // 默认使用JPEG格式（对照片类图片效果好）
            outputFormat = 'image/jpeg';
          }
        }
        
        // 设置压缩质量
        quality = settings.quality / 100;
        
        // 无损模式时提高底线
        if (isPro.value && settings.mode === 'lossless') {
          quality = Math.max(0.8, quality);
        }
        
        // 输出压缩后的图片
        compressedDataUrl = canvas.toDataURL(outputFormat, quality);
        
        // 将base64转换为Blob以便下载和准确计算大小
        const byteString = atob(compressedDataUrl.split(',')[1]);
        const mimeType = compressedDataUrl.split(',')[0].split(':')[1].split(';')[0];
        const ab = new ArrayBuffer(byteString.length);
        const ia = new Uint8Array(ab);
        
        for (let i = 0; i < byteString.length; i++) {
          ia[i] = byteString.charCodeAt(i);
        }
        
        const blob = new Blob([ab], { type: mimeType });
        const compressedSize = blob.size; // 使用Blob的实际大小，更准确
        const downloadUrl = URL.createObjectURL(blob);
        
        // 如果压缩后反而变大了，就使用原图（只在压缩模式下）
        if (compressedSize > originalSize && settings.mode !== 'lossless') {
          // 添加到结果列表，但提示用户原图已经足够小
          compressionResults.value.push({
            fileName: file.name,
            originalSize: originalSize,
            compressedSize: originalSize, // 使用原始大小
            originalUrl: originalDataUrl,
            compressedUrl: originalDataUrl, // 使用原图
            downloadUrl: originalDataUrl, // 使用原图URL
            format: file.type.split('/')[1],
            usedOriginal: true // 标记使用了原图
          });
          
          // 显示提示
          ElMessage.info(`图片"${file.name}"已经很小，无需压缩。`);
        } else {
          // 正常添加压缩结果
          compressionResults.value.push({
            fileName: file.name,
            originalSize: originalSize,
            compressedSize: compressedSize,
            originalUrl: originalDataUrl,
            compressedUrl: compressedDataUrl,
            downloadUrl: downloadUrl,
            format: mimeType.split('/')[1],
            usedOriginal: false
          });
        }
        
        resolve();
      };
      
      img.src = originalDataUrl;
    };
    
    reader.readAsDataURL(file);
  });
};

// 预览图片
const previewImage = (imageData) => {
  currentPreview.value = imageData;
  previewVisible.value = true;
};

// 下载图片
const downloadImage = (imageData) => {
  const link = document.createElement('a');
  link.href = imageData.downloadUrl;
  // 确保文件扩展名与实际格式匹配
  const fileExt = imageData.format.replace('jpeg', 'jpg');
  const baseName = imageData.fileName.substring(0, imageData.fileName.lastIndexOf('.')) || imageData.fileName;
  link.download = `compressed_${baseName}.${fileExt}`;
  link.click();
  
  // 为防止内存泄漏，下载后释放URL对象
  setTimeout(() => {
    URL.revokeObjectURL(imageData.downloadUrl);
  }, 100);
};

// 打包下载全部
const downloadAll = () => {
  if (compressionResults.value.length <= 1) {
    // 单个文件直接调用下载
    if (compressionResults.value.length === 1) {
      downloadImage(compressionResults.value[0]);
    }
    return;
  }
  
  // 实际应用中应使用JSZip等库创建ZIP文件
  // 简化处理：依次下载所有文件
  compressionResults.value.forEach((result, index) => {
    // 稍微延迟每个下载，避免浏览器阻止
    setTimeout(() => {
      downloadImage(result);
    }, index * 300);
  });
  
  ElMessage.info('正在依次下载多个文件...');
};

// 重置表单
const resetForm = () => {
  settings.quality = 75;
  settings.resize = false;
  settings.maxSize = 2000;
  settings.mode = 'lossy';
  settings.outputFormat = 'same';
  settings.addWatermark = false;
  settings.watermarkType = 'text';
  settings.watermarkText = '柯基工具箱';
  
  // 清空上传文件
  if (uploadRef.value) {
    uploadRef.value.clearFiles();
  }
  
  // 清空预览
  previewImageUrl.value = '';
  previewImageName.value = '';
  previewImageSize.value = '';
  
  // 清空结果
  compressionResults.value = [];
};

// 升级会员
const handleUpgrade = () => {
  // 使用 Vue Router 导航到会员页面，使用命名路由而不是路径
  router.push({ name: 'membership' });
};

// 移除已上传的图片
const removeUploadedImage = () => {
  if (uploadRef.value) {
    uploadRef.value.clearFiles();
  }
  previewImageUrl.value = '';
  previewImageName.value = '';
  previewImageSize.value = '';
};

// 辅助函数 - 从大小字符串解析为字节数
const parseFileSizeToBytes = (sizeStr) => {
  try {
    const parts = sizeStr.split(' ');
    const value = parseFloat(parts[0]);
    const unit = parts[1];
    
    switch (unit) {
      case 'KB': return value * 1024;
      case 'MB': return value * 1024 * 1024;
      case 'GB': return value * 1024 * 1024 * 1024;
      default: return value;
    }
  } catch (e) {
    return 1024 * 1024; // 默认返回1MB
  }
};

// 辅助函数 - 从URL猜测文件类型
const guessFileTypeFromUrl = (url) => {
  if (url.includes('data:image/jpeg')) return 'image/jpeg';
  if (url.includes('data:image/png')) return 'image/png';
  if (url.includes('data:image/webp')) return 'image/webp';
  return 'image/jpeg'; // 默认
};

// 辅助函数 - 将URL转换为File对象
const urlToFile = async (url, fileName) => {
  const res = await fetch(url);
  const blob = await res.blob();
  return new File([blob], fileName, { type: blob.type });
};

// 修正格式化尺寸变化
const formatSizeChange = (originalSize, compressedSize) => {
  const saved = originalSize - compressedSize;
  const percentage = Math.round((saved / originalSize) * 100);
  
  if (percentage >= 0) {
    return `节省了 ${percentage}%`;
  } else {
    // 这种情况应该很少出现，因为我们会使用原图
    return `增加了 ${Math.abs(percentage)}%`;
  }
};
</script>

<style scoped>
.image-compressor {
  width: 100%;
  max-width: 100%;
  margin: 0 auto;
}

.tool-card {
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08);
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px 24px;
  background: linear-gradient(135deg, #3498db, #2980b9);
}

.card-header h3 {
  margin: 0;
  color: white;
  font-size: 20px;
  font-weight: 600;
  letter-spacing: 0.5px;
}

.tool-description {
  margin: 24px 0;
  padding: 0 12px;
  color: #606266;
  font-size: 16px;
  line-height: 1.6;
}

.pro-features {
  margin-bottom: 28px;
  padding: 0 12px;
}

.limit-info {
  margin: 16px 0;
}

.limit-info p {
  margin: 8px 0;
  position: relative;
  padding-left: 20px;
  font-size: 14px;
}

.limit-info p::before {
  content: "•";
  position: absolute;
  left: 0;
  color: #e6a23c;
  font-weight: bold;
  font-size: 18px;
}

.upload-area {
  padding: 20px 0;
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  justify-content: space-between;
}

.upload-card {
  flex: 1;
  min-width: 350px;
  max-width: 550px;
  height: 100%;
}

.settings-card {
  flex: 1;
  min-width: 350px;
}

.results-area {
  margin-top: 20px;
}

.upload-container {
  border-radius: 12px;
  background-color: #f8f9fa;
  padding: 24px;
  height: 100%;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
  border: 1px solid #ebeef5;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.upload-container h4 {
  margin-top: 0;
  margin-bottom: 20px;
  color: #303133;
  font-size: 18px;
  font-weight: 600;
  position: relative;
  padding-left: 14px;
}

.upload-container h4::before {
  content: "";
  position: absolute;
  left: 0;
  top: 4px;
  bottom: 4px;
  width: 4px;
  background: #3498db;
  border-radius: 4px;
}

.image-uploader {
  width: 100%;
  border-radius: 12px;
  overflow: hidden;
}

.upload-icon {
  font-size: 36px;
  color: #3498db;
  margin-bottom: 12px;
}

.upload-text {
  color: #606266;
  font-size: 16px;
  text-align: center;
  margin-bottom: 8px;
}

.upload-text em {
  color: #3498db;
  font-style: normal;
  font-weight: 600;
}

.upload-tip {
  font-size: 13px;
  color: #909399;
  margin-top: 12px;
}

.upload-preview {
  margin-top: 20px;
  padding: 16px;
  background-color: white;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.02);
}

.preview-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.preview-header h5 {
  margin: 0;
  color: #303133;
  font-size: 18px;
  font-weight: 600;
}

.preview-image-container {
  display: flex;
  align-items: center;
  gap: 16px;
}

.preview-image {
  width: 120px;
  height: 120px;
  object-fit: cover;
  border-radius: 8px;
}

.preview-info {
  display: flex;
  flex-direction: column;
}

.preview-info span {
  color: #606266;
  font-size: 14px;
}

.compression-settings {
  background-color: #f8f9fa;
  padding: 24px;
  border-radius: 12px;
  margin-top: 20px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
  border: 1px solid #ebeef5;
}

.compression-settings h4 {
  margin-top: 0;
  margin-bottom: 20px;
  color: #303133;
  font-size: 18px;
  font-weight: 600;
  position: relative;
  padding-left: 14px;
}

.compression-settings h4::before {
  content: "";
  position: absolute;
  left: 0;
  top: 4px;
  bottom: 4px;
  width: 4px;
  background: #3498db;
  border-radius: 4px;
}

.settings-form {
  margin-bottom: 24px;
}

.el-form-item {
  margin-bottom: 22px;
}

.watermark-settings {
  margin-top: 16px;
  padding: 16px;
  background-color: white;
  border-radius: 8px;
  border: 1px dashed #dcdfe6;
}

.watermark-uploader {
  width: 120px;
  height: 120px;
  border: 2px dashed #d9d9d9;
  border-radius: 8px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: all 0.3s ease;
  background-color: #fafafa;
}

.watermark-uploader:hover {
  border-color: #3498db;
  background-color: #f0f9ff;
}

.watermark-uploader-icon {
  font-size: 32px;
  color: #8c939d;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.watermark-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.compression-actions {
  display: flex;
  gap: 12px;
  margin-top: 24px;
}

.compression-actions .el-button {
  padding: 12px 24px;
  font-weight: 500;
}

.compression-progress {
  margin: 28px 12px;
  padding: 24px;
  background-color: #f0f9ff;
  border-radius: 12px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
}

.progress-info {
  text-align: center;
  margin-top: 16px;
  color: #606266;
  font-size: 14px;
}

.results-section {
  margin-top: 36px;
  padding: 0 12px;
}

.results-section h4 {
  margin-bottom: 20px;
  color: #303133;
  font-size: 18px;
  font-weight: 600;
  position: relative;
  padding-left: 14px;
}

.results-section h4::before {
  content: "";
  position: absolute;
  left: 0;
  top: 4px;
  bottom: 4px;
  width: 4px;
  background: #3498db;
  border-radius: 4px;
}

.el-table {
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
}

.size-change {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 8px;
}

.size-change .el-icon {
  color: #3498db;
}

.compression-rate {
  margin-bottom: 4px;
}

.compression-rate :deep(.el-progress__text) {
  font-size: 13px !important;
  font-weight: 600;
  color: #3498db;
}

.batch-actions {
  margin-top: 24px;
  text-align: right;
}

.image-comparison {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.comparison-container {
  display: flex;
  gap: 24px;
}

.comparison-original,
.comparison-compressed {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.comparison-original h4,
.comparison-compressed h4 {
  margin-bottom: 12px;
  color: #303133;
  font-size: 16px;
  font-weight: 600;
}

.image-wrapper {
  position: relative;
  border: 1px solid #ebeef5;
  border-radius: 8px;
  overflow: hidden;
  margin-bottom: 12px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
  transition: transform 0.3s ease;
}

.image-wrapper:hover {
  transform: none;
}

/* 修改为条件应用hover效果的选择器 */
.comparison-container:hover .image-wrapper {
  transform: none;
}

.image-wrapper:hover {
  transform: none;
}

/* 只有当用户使用放大镜功能并且鼠标在图片上时才应用细微的放大效果 */
.comparison-container .image-wrapper:focus-within,
.comparison-container .image-wrapper:hover:active {
  transform: scale(1.01);
}

/* 确保图片容器有正确的尺寸限制 */
.image-wrapper img {
  width: 100%;
  height: auto;
  display: block;
  max-height: 70vh;
  object-fit: contain;
}

.image-info {
  padding: 12px;
  background-color: #f8f9fa;
  border-radius: 8px;
  font-size: 14px;
  color: #606266;
}

.image-info p {
  margin: 4px 0;
}

.comparison-tools {
  display: none;
}

.error-message {
  margin-bottom: 20px;
}

/* 自定义Element Plus组件样式 */
:deep(.el-upload-dragger) {
  border-radius: 12px;
  padding: 32px;
  transition: all 0.3s ease;
  border: 2px dashed #dcdfe6;
  margin-top: 12px;
  background-color: white;
}

:deep(.el-upload-dragger:hover) {
  border-color: #3498db;
  background-color: #f0f9ff;
}

:deep(.el-upload__tip) {
  margin-top: 12px;
  text-align: center;
}

:deep(.el-upload-list) {
  margin-top: 16px;
}

:deep(.el-slider__runway) {
  height: 6px;
  background-color: #e4e7ed;
}

:deep(.el-slider__bar) {
  height: 6px;
  background-color: #3498db;
}

:deep(.el-slider__button) {
  width: 18px;
  height: 18px;
  border: 2px solid #3498db;
  background-color: white;
}

:deep(.el-input-number .el-input__wrapper) {
  border-radius: 8px;
}

:deep(.el-checkbox__input.is-checked .el-checkbox__inner) {
  background-color: #3498db;
  border-color: #3498db;
}

:deep(.el-radio__input.is-checked .el-radio__inner) {
  background-color: #3498db;
  border-color: #3498db;
}

:deep(.el-button--primary) {
  background-color: #3498db;
  border-color: #3498db;
}

:deep(.el-button--primary:hover) {
  background-color: #2980b9;
  border-color: #2980b9;
}

:deep(.el-button--warning) {
  background-color: #e6a23c;
  border-color: #e6a23c;
}

:deep(.el-tabs__item.is-active) {
  color: #3498db;
}

:deep(.el-tabs__active-bar) {
  background-color: #3498db;
}

@media (min-width: 992px) {
  .upload-container {
    padding-bottom: 36px; /* 增加底部内边距，平衡视觉高度 */
  }
}

@media (max-width: 768px) {
  .comparison-container {
    flex-direction: column;
  }
  
  .compression-settings {
    padding: 18px;
  }
  
  .card-header {
    padding: 16px 18px;
  }
}

.usage-section {
  margin-top: 36px;
  padding: 0 12px;
  margin-bottom: 32px;
}

.usage-wrapper {
  background-color: #f8f9fa;
  border-radius: 12px;
  padding: 24px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
  border: 1px solid #ebeef5;
}

.usage-title-section {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 24px;
}

.usage-icon {
  color: #3498db;
}

.usage-title-section h2 {
  margin: 0;
  color: #303133;
  font-size: 20px;
  font-weight: 600;
}

.usage-content {
  display: flex;
  flex-direction: column;
}

.guide-steps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 24px;
  margin-bottom: 24px;
}

.step-item {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  background-color: white;
  padding: 16px;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.02);
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.step-item:hover {
  transform: translateY(-3px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}

.step-number {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background-color: #3498db;
  color: white;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 16px;
  font-weight: 600;
  flex-shrink: 0;
}

.step-content {
  flex: 1;
}

.step-content h4 {
  margin: 0 0 8px 0;
  color: #303133;
  font-size: 16px;
  font-weight: 600;
}

.step-content p {
  margin: 0;
  color: #606266;
  font-size: 14px;
  line-height: 1.5;
}

.pro-tip {
  margin-top: 8px;
  padding: 16px;
  background-color: white;
  border-radius: 8px;
  border: 1px dashed #e6a23c;
  display: flex;
  align-items: center;
  gap: 12px;
}

.pro-tip .el-icon {
  color: #e6a23c;
  font-size: 20px;
  flex-shrink: 0;
}

.pro-tip span {
  color: #606266;
  font-size: 14px;
  line-height: 1.5;
}

@media (max-width: 768px) {
  .guide-steps {
    grid-template-columns: 1fr;
  }
}

@media (min-width: 992px) {
  .upload-section {
    grid-template-columns: 1fr 1fr;
    align-items: stretch;
  }
  
  .compression-settings {
    margin-top: 0;
    height: 100%;
  }
}

@media (min-width: 992px) {
  .results-section .batch-actions {
    margin-right: 12px;
  }
}

/* 鼠标离开屏幕时撤销所有可能的放大效果 */
.el-dialog__wrapper {
  overflow: hidden;
}

/* 修改Dialog的弹出动画，确保它更稳定 */
:deep(.el-dialog) {
  transform-origin: center center;
  transition: all 0.2s cubic-bezier(0.25, 0.8, 0.25, 1);
  margin-top: 5vh !important; /* 调整弹窗位置，更靠上 */
}

/* 确保对话框内容不会因鼠标移动而改变 */
:deep(.el-dialog__body) {
  overflow: auto;
  max-height: 80vh;
}

/* 修改对话框标题，增加放大镜提示 */
:deep(.el-dialog__header) {
  padding-bottom: 15px;
  border-bottom: 1px solid #f0f0f0;
}

/* 确保对话框遮罩层处理正确 */
:deep(.el-dialog__wrapper) {
  overflow: hidden !important;
  position: fixed !important;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}

:deep(.el-overlay) {
  position: fixed !important; 
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background-color: rgba(0, 0, 0, 0.5) !important;
  overflow: auto;
  margin: 0;
  z-index: 2000;
}
</style> 